package com.sunseaypw.console;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import com.sunseaypw.base.MyLogger;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Scope;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

@Component //bean的id/name缺省为 类名首字母小写 springAbout
@Scope("prototype") 
public class SpringAbout {
    public static void main(String[] args){
        MyLogger.info("开始进来了","main");
        System.out.println( "Hello World!" );
        var c =new SpringAbout();
        if(c!=null){
            c.firstTest();
        }
        MyLogger.warn("结束了","main2222");
    }    
    public void firstTest(){
        /* 这种会一次性加载扫描加载实例化所有bean，可以进行完整检验，避免运行过程中出现临时性异常 */
        ApplicationContext ctx=new MyClassPathXmlApplicationContext("application.xml");
        SpringBean c=(SpringBean)ctx.getBean(com.sunseaypw.console.SpringBean.class);
        System.out.println("user_name111111:"+c.getUser().getName());  
        SpringBean c1=(SpringBean)ctx.getBean("springBean");
        System.out.println("两次调用是否是同一个实例:"+(c==c1));  
        /**在Spring中同时使用XML和注解方式，可能由于缺省名称不同，所以会构造两个同类型的bean，但在代码中用类型获取bean时，就会出现非唯一异常 */
        try{
            User u1=(User)ctx.getBean(com.sunseaypw.console.User.class);
            System.out.println("user_name222222:"+u1.getName());   
        }catch(Exception ex){
            System.out.println(ex.toString());   
        }

        String s1=(String)ctx.getBean(String.class);
        System.out.println("strBean-hasCode:"+s1.hashCode());  
        String s2=(String)ctx.getBean(String.class);
        System.out.println("strBean-hasCode:"+s2.hashCode());  

        NestClass nc=(NestClass)ctx.getBean("nestClass0000");
        System.out.println("内嵌静态类bean对象的username:"+nc.getUserName());  
        NestClass nc1=(NestClass)ctx.getBean("nestClass111");
        System.out.println("内嵌静态类bean对象11111111的username:"+nc1.getUserName());  

        User u222=(User)ctx.getBean("userService787878");
        System.out.println("第二个配置文件中的bean:"+u222.getName());   
                        
    }
    public static class NestClass{
        private User u;
        public NestClass(User u){
            this.u=u;
        }
        public String getUserName(){
            System.out.println("当前set注入username是："+this.su.getName());
            return u.getName();
        }
        private User su;
        public void setMyFamily(User su){
            this.su=su;
        }        
    }
    /* 避免多个配置文件中出现同名bean后静默造成业务逻辑异常问题，将此修改为抛出异常！！ */
    public static class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext{
        public MyClassPathXmlApplicationContext(String...configures){
            super(configures);
        }
        @Override
        protected void customizeBeanFactory(org.springframework.beans.factory.support.DefaultListableBeanFactory beanFactory) {
            super.setAllowBeanDefinitionOverriding(false);        
            super.customizeBeanFactory(beanFactory);
        }
    }
}
